package com.gc.cscott.cli;

import com.gc.cscott.domain.contest.numbers.TaskNumber;
import com.gc.cscott.domain.contest.numbers.TestCaseNumber;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;

/**
 *
 * @author dmitry.mamonov
 */
public class Parser {

    private static final Pattern rangePattern = Pattern.compile("^(\\d+)-(\\d+)$");
    private static final String rangesRegexp = "((\\d+)|(\\d+-\\d+))(,((\\d+)|(\\d+-\\d+)))*";
    private static final Pattern taskListPattern = Pattern.compile("^T" + rangesRegexp + "$");
    private static final Pattern testCaseListPattern = Pattern.compile("^t" + rangesRegexp + "$");
    private static final Pattern solutionsListPattern = Pattern.compile("^S" + rangesRegexp + "$");

    public static List<TaskNumber> parseTaskList(String param) {
        List<Integer> plainResult = parseList(taskListPattern, param);
        if (plainResult == null) {
            return null;
        } else {
            ImmutableList.Builder<TaskNumber> result = ImmutableList.<TaskNumber>builder();
            for (Integer number : plainResult) {
                result.add(new TaskNumber(number));
            }
            return result.build();
        }
    }

    public static List<TestCaseNumber> parseTestCaseList(String param) {
        List<Integer> plainResult = parseList(testCaseListPattern, param);
        if (plainResult == null) {
            return null;
        } else {
            ImmutableList.Builder<TestCaseNumber> result = ImmutableList.<TestCaseNumber>builder();
            for (Integer number : plainResult) {
                result.add(new TestCaseNumber(number));
            }
            return result.build();
        }
    }

    public static List<Integer> parseSolutionList(String param) {
        List<Integer> plainResult = parseList(solutionsListPattern, param);
        if (plainResult == null) {
            return null;
        } else {
            return ImmutableList.copyOf(plainResult);
        }
    }

    private static List<Integer> parseList(Pattern pattern, String param) {
        Matcher matcher = pattern.matcher(param);
        if (matcher.matches() == true) {
            ImmutableList.Builder<Integer> result = ImmutableList.<Integer>builder();
            for (int i = 0; i < matcher.groupCount(); i++) {
                String group = matcher.group(i);
                if (group != null) {
                    if (StringUtils.isNumeric(group)) {
                        result.add(Integer.parseInt(group));
                    }
                    Matcher rangeMatcher = rangePattern.matcher(group);
                    if (rangeMatcher.matches() == true) {
                        final int rangeStart = Integer.parseInt(rangeMatcher.group(1));
                        final int rangeEnd = Integer.parseInt(rangeMatcher.group(2));
                        for (int valueInRange = rangeStart; valueInRange <= rangeEnd; valueInRange++) {
                            result.add(valueInRange);
                        }
                    }
                    //in other case ignore separators data.
                }
            }
            return result.build();
        } else {
            return null;
        }
    }
}
